EC2 Image BuilderでWindows ServerのAMIを作成してみた #reinvent
中山(順)@東京です。
re:Invent 2019 開催中ですね。
今回は、EC2 Image BuilderでWindows ServerのAMIを作成してみました。
EC2 Image Builderとは
AMI (Amazon Machine Image) の作成を自動化するための機能です。
EC2 Image BuilderではAMIを作成するための一連の処理を "Pipeline" として定義します。 Pipelineを定義する中で「どのイメージをベースにするか」「ビルドフェーズで何をするか」「テストフェーズで何をするか」を定義します。 この3つはEC2 Image Builderの中で "Recipe" というリソースとして定義されます。 そのほか、「イメージをいつ作成するのか(マニュアル / スケジュール)」「イメージのビルドをどのVPCで行うのか」「ログをどこに出力するのか」などを設定します。
EC2 Image Builderは現時点で以下のOSをサポートしています。
- Amazon Linux 2
- Windows Server 2019 / 2016 / 2012 R2
また、ビルドフェーズおよびテストフェーズでは複数の処理単位を実行することができます。 この処理単位は "Component" として定義されます。 Componentの定義方法は以下のドキュメントを参照してください。
また、ドキュメントの中で利用できるアクションはこちらを参照してください。
やってみた
今回は以下のブログ記事で紹介されている処理の一部をビルドフェーズで実行してみたいと思います。
PowerShellスクリプトサンプル(Windows Server環境構築 初期設定の一括実行) – 2017年夏ver.
Documentの作成
3分間クッキング方式で大変恐縮ですが、以下のようなドキュメントを作成しました。
name: my-basic-setting description: 'Ore no ami' schemaVersion: 1.0 phases: - name: build steps: - name: DisableWindowsFirewall action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False' - name: CreateToolDirectory action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'mkdir C:\tools' - name: SetEnvironmentVarialbe action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - '$path = [Environment]::GetEnvironmentVariable(''PATH'', ''Machine'')' - '$path += ";" + "C:\tools\nkf" + ";" + "C:\tools\gzip"' - '[Environment]::SetEnvironmentVariable(''PATH'', $path, ''Machine'')' - name: InstallFirefox action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'Invoke-WebRequest -Uri "https://ftp.mozilla.org/pub/firefox/releases/70.0.1/win64/ja/Firefox%20Setup%2070.0.1.exe" -OutFile C:\tools\firefox.exe' - 'C:\tools\firefox.exe -ms' - name: InstallChocolatey action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'iex ((New-Object System.Net.WebClient).DownloadString(''https://chocolatey.org/install.ps1''))' - name: RebootAfterConfigApplied action: Reboot inputs: delaySeconds: 60 - name: InstallGit action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'choco install -y git' - name: InstallPython3 action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'choco install -y python3' - name: InstallCurl action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'choco install -y curl' - name: RebootAfterConfigApplied02 action: Reboot inputs: delaySeconds: 60
name: test-my-basic-setting description: 'Ore no test' schemaVersion: 1.0 phases: - name: test steps: - name: GetWindowsFirewall action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'Get-NetFirewallProfile' - name: DescribeToolDirectory action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'ls C:\tools' - name: GetEnvironmentVarialbe action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'Get-ChildItem env:Path' - name: GetFirefox action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'Get-ChildItem -Path(''HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'') | % { Get-ItemProperty $_.PsPath | Select-Object DisplayName, DisplayVersion, Publisher, PSPath}' - name: TestChocolatey action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'choco -v' - name: TestGit action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'git --version' - name: TestPython3 action: ExecutePowerShell timeoutSeconds: 120 onFailure: Abort maxAttempts: 3 inputs: commands: - 'python --version'
Componentの作成
上記のDocumentを利用してComponentを作成します。
まずはBuildのためのComponentを作成します。
次にTest用のComponentを作成します。
この2つのComponentを使ってImageを作成します。
PipelineおよびRecipeの作成
Pipelineを作成します。
OSはWindows Server 2019を利用してみます。
BuildのためのComponentには先ほど作成したものを利用します。
次に、Recipeの名前やBuild / Testの為に作成されるEC2インスタンスに設定するIAM Role / Instance Profileを設定します。
動作確認のためにS3にログを出力します。
それ以外の設定は基本的にデフォルトとします。
設定を確認し、Pipelineの作成を完了します。
Imageの作成とログの確認
作成したPipelineを利用してImageをBuildします。
イメージが作成できました。
ログを確認します。 標準出力の結果は以下の通りで、問題なさそうです。(環境変数の部分は表示が切れていて確認できませんでしたが・・・)
2019-12-03 12:03:33 Info Document TOE_2019-12-03_12-03-31_UTC-0_ec891787-15c4-11ea-a476-0a728ba491f4/test-test_1152921504606846977.ps1 2019-12-03 12:03:33 Info Phase test 2019-12-03 12:03:33 Info Step GetWindowsFirewall 2019-12-03 12:03:35 Info Command execution completed successfully 2019-12-03 12:03:35 Info Stdout: Name : Domain Enabled : False DefaultInboundAction : NotConfigured DefaultOutboundAction : NotConfigured AllowInboundRules : NotConfigured AllowLocalFirewallRules : NotConfigured AllowLocalIPsecRules : NotConfigured AllowUserApps : NotConfigured AllowUserPorts : NotConfigured AllowUnicastResponseToMulticast : NotConfigured NotifyOnListen : False EnableStealthModeForIPsec : NotConfigured LogFileName : %systemroot%\system32\LogFiles\Firewall\pfirewall.log LogMaxSizeKilobytes : 4096 LogAllowed : False LogBlocked : False LogIgnored : NotConfigured DisabledInterfaceAliases : {NotConfigured} Name : Private Enabled : False DefaultInboundAction : NotConfigured DefaultOutboundAction : NotConfigured AllowInboundRules : NotConfigured AllowLocalFirewallRules : NotConfigured AllowLocalIPsecRules : NotConfigured AllowUserApps : NotConfigured AllowUserPorts : NotConfigured AllowUnicastResponseToMulticast : NotConfigured NotifyOnListen : False EnableStealthModeForIPsec : NotConfigured LogFileName : %systemroot%\system32\LogFiles\Firewall\pfirewall.log LogMaxSizeKilobytes : 4096 LogAllowed : False LogBlocked : False LogIgnored : NotConfigured DisabledInterfaceAliases : {NotConfigured} Name : Public Enabled : False DefaultInboundAction : NotConfigured DefaultOutboundAction : NotConfigured AllowInboundRules : NotConfigured AllowLocalFirewallRules : NotConfigured AllowLocalIPsecRules : NotConfigured AllowUserApps : NotConfigured AllowUserPorts : NotConfigured AllowUnicastResponseToMulticast : NotConfigured NotifyOnListen : False EnableStealthModeForIPsec : NotConfigured LogFileName : %systemroot%\system32\LogFiles\Firewall\pfirewall.log LogMaxSizeKilobytes : 4096 LogAllowed : False LogBlocked : False LogIgnored : NotConfigured DisabledInterfaceAliases : {NotConfigured} 2019-12-03 12:03:35 Info Stderr: 2019-12-03 12:03:35 Info ExitCode 0 2019-12-03 12:03:35 Info Step DescribeToolDirectory 2019-12-03 12:03:35 Info Command execution completed successfully 2019-12-03 12:03:35 Info Stdout: Directory: C:\tools Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 12/3/2019 11:41 AM 52023592 firefox.exe 2019-12-03 12:03:35 Info Stderr: 2019-12-03 12:03:35 Info ExitCode 0 2019-12-03 12:03:35 Info Step GetEnvironmentVarialbe 2019-12-03 12:03:36 Info Command execution completed successfully 2019-12-03 12:03:36 Info Stdout: Name Value ---- ----- Path C:\Python38\Scripts\;C:\Python38\;C:\Windows\system32;C:\Windows;C:\Windows\System32\... 2019-12-03 12:03:36 Info Stderr: 2019-12-03 12:03:36 Info ExitCode 0 2019-12-03 12:03:36 Info Step GetFirefox 2019-12-03 12:03:36 Info Command execution completed successfully 2019-12-03 12:03:36 Info Stdout: DisplayName DisplayVersion Publisher PSPath ----------- -------------- --------- ------ Microsoft.PowerShell.Core\R... Git version 2.24.0.2 2.24.0.2 The Git Development Community Microsoft.PowerShell.Core\R... Mozilla Firefox 70.0.1 (x64 ja) 70.0.1 Mozilla Microsoft.PowerShell.Core\R... Mozilla Maintenance Service 70.0.1 Mozilla Microsoft.PowerShell.Core\R... Microsoft.PowerShell.Core\R... Python 3.8.0 Core Interpreter (64-bit) 3.8.150.0 Python Software Foundation Microsoft.PowerShell.Core\R... Python 3.8.0 Tcl/Tk Support (64-bit) 3.8.150.0 Python Software Foundation Microsoft.PowerShell.Core\R... aws-cfn-bootstrap 1.4.31 Amazon Web Services Microsoft.PowerShell.Core\R... Python 3.8.0 Utility Scripts (64-bit) 3.8.150.0 Python Software Foundation Microsoft.PowerShell.Core\R... Python 3.8.0 Add to Path (64-bit) 3.8.150.0 Python Software Foundation Microsoft.PowerShell.Core\R... Python 3.8.0 Standard Library (64-bit) 3.8.150.0 Python Software Foundation Microsoft.PowerShell.Core\R... Python 3.8.0 Development Libraries (64-bit) 3.8.150.0 Python Software Foundation Microsoft.PowerShell.Core\R... Python 3.8.0 Documentation (64-bit) 3.8.150.0 Python Software Foundation Microsoft.PowerShell.Core\R... Python 3.8.0 Executables (64-bit) 3.8.150.0 Python Software Foundation Microsoft.PowerShell.Core\R... Amazon SSM Agent 2.3.722.0 Amazon Web Services Microsoft.PowerShell.Core\R... AWS PV Drivers 8.3.2 Amazon Web Services Microsoft.PowerShell.Core\R... Python 3.8.0 pip Bootstrap (64-bit) 3.8.150.0 Python Software Foundation Microsoft.PowerShell.Core\R... Python 3.8.0 Test Suite (64-bit) 3.8.150.0 Python Software Foundation Microsoft.PowerShell.Core\R... 2019-12-03 12:03:36 Info Stderr: 2019-12-03 12:03:36 Info ExitCode 0 2019-12-03 12:03:36 Info Step TestChocolatey 2019-12-03 12:03:37 Info Command execution completed successfully 2019-12-03 12:03:37 Info Stdout: 0.10.15 2019-12-03 12:03:37 Info Stderr: 2019-12-03 12:03:37 Info ExitCode 0 2019-12-03 12:03:37 Info Step TestGit 2019-12-03 12:03:38 Info Command execution completed successfully 2019-12-03 12:03:38 Info Stdout: git version 2.24.0.windows.2 2019-12-03 12:03:38 Info Stderr: 2019-12-03 12:03:38 Info ExitCode 0 2019-12-03 12:03:38 Info Step TestPython3 2019-12-03 12:03:38 Info Command execution completed successfully 2019-12-03 12:03:38 Info Stdout: Python 3.8.0 2019-12-03 12:03:38 Info Stderr: 2019-12-03 12:03:38 Info ExitCode 0 2019-12-03 12:03:38 Info Document TOE_2019-12-03_12-03-31_UTC-0_ec891787-15c4-11ea-a476-0a728ba491f4/test-build_1152921504606846977.ps1
まとめ
以上のようにWindowsでもImageの作成を自動化することができました。 欲を言えばAnsibleやGitHub等との連携がもっと簡単にできるとさらに使い勝手が良くなりそうと思いました。
Windowsでも非常に簡単に利用できますので活用していきましょう。
現場からは以上です。(東京にいるけど)